package com.doge.walknovel.business.home.discover.widgets

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.OnLifecycleEvent
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import com.doge.wnpro.R
import com.doge.walknovel.utils.RoundedCorners12
import com.doge.walknovel.utils.load
import com.doge.walknovel.utils.rxInterval
import com.doge.walknovel.utils.screenWidth
import io.reactivex.disposables.Disposable

class BannerView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null
) : ViewPager(context, attrs) {
    private var task: Disposable? = null
    private var listener: ((Any) -> Unit)? = null
    private val delayTime = 5000L
    private val lifecycleObserver = object : LifecycleObserver {
        @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
        fun onPause() = stopAutoPlay()

        @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
        fun onResume() = startAutoPlay()
    }

    private fun startAutoPlay() {
        task?.dispose()
        if (((adapter as? BannerPagerAdapter<*>?)?.getRealCount() ?: 0) <= 1) return

        task = rxInterval(delayTime) {
            val count = adapter?.count ?: 0
            if (count > 1) {
                val nextItem = (currentItem + 1) % count
                if (nextItem == 0) {
                    setCurrentItem(nextItem, false)
                } else {
                    currentItem = nextItem
                }
            }
        }
    }

    private fun stopAutoPlay() {
        task?.dispose()
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        (context as? LifecycleOwner?)?.lifecycle?.removeObserver(lifecycleObserver)
        stopAutoPlay()
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        (context as? LifecycleOwner?)?.lifecycle?.addObserver(lifecycleObserver)
        startAutoPlay()
    }

    fun <T> set(dataList: List<T>, url: (T) -> String?) {
        if (dataList.isEmpty()) return
        adapter = BannerPagerAdapter(dataList, url) {
            listener?.invoke(it as Any)
        }
        startAutoPlay()
    }

    fun setListener(callback: ((Any) -> Unit)? = null) {
        listener = callback
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        val action = ev.actionMasked
        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL
            || action == MotionEvent.ACTION_OUTSIDE
        ) {
            startAutoPlay()
        } else if (action == MotionEvent.ACTION_DOWN) {
            stopAutoPlay()
        }
        return super.dispatchTouchEvent(ev)
    }

    class BannerPagerAdapter<T>(
        private val dataList: List<T>,
        private val url: (T) -> String?,
        private val callback: (T) -> Unit
    ) : PagerAdapter() {
        override fun isViewFromObject(view: View, `object`: Any) = view === `object`
        override fun getCount(): Int = Int.MAX_VALUE
        override fun instantiateItem(container: ViewGroup, position: Int): Any {
            return ImageView(container.context).apply {
                container.addView(this)
                scaleType = ImageView.ScaleType.CENTER_CROP
                val realPosition = position % dataList.size
                val data = dataList[realPosition]
                // TODO thumbnails
                load(
                    url(data),
                    R.drawable.shape_f7f7f7_12,
                    transformation = RoundedCorners12,
                    width = screenWidth,
                    height = (screenWidth / 335f * 134).toInt()
                )
                setOnClickListener { callback.invoke(data) }
            }
        }

        fun getRealCount(): Int = dataList.size
        override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
            container.removeView(`object` as View)
        }
    }
}